package com.cakeclient;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import com.cakeclient.clientsoap.CakeClientSoapClient;
import com.cakeclient.clientsoap.Exception.SoapClientException;
import com.cakeclient.clientsoap.Exception.SoapComException;
import com.cakeclient.clientsoap.contract.*;
import com.cakeclient.database.*;

import java.util.List;


public class SyncTaskManager {

    public static boolean syncStores(Context context, List<Store> stores) {

        OurSQLiteOpenHelper ourSQLiteOpenHelper = new OurSQLiteOpenHelper(context);

        ourSQLiteOpenHelper.truncateTable(StoreTable.getInstance());
        ourSQLiteOpenHelper.close();

        for (Store store : stores) {
            new com.cakeclient.Model.Store(context, store).saveToDatabase(context);
        }
        return true;
    }

    public static boolean syncCatalog(Context context, Catalog catalog) {
        OurSQLiteOpenHelper ourSQLiteOpenHelper = new OurSQLiteOpenHelper(context);

        ourSQLiteOpenHelper.truncateTable(new DatabaseTable[]{
                OrderTable.getInstance(),
                UnitarySaleTable.getInstance(),
                ProductTable.getInstance(),
                MenuTypeTable.getInstance()
        });
        ourSQLiteOpenHelper.close();

        for (ProductType productType : catalog.products) {
            new com.cakeclient.Model.ProductType(context, productType).saveToDatabase(context);
        }
        for (ProductCategory productCategory : catalog.categories) {
            new com.cakeclient.Model.CatalogCategory(context, productCategory).saveToDatabase(context);
        }
        for (ProductCategory productCategory : catalog.categories) {
            new com.cakeclient.Model.CatalogCategory(context, productCategory).saveToDatabase(context);
        }

        return true;
    }


    public static boolean syncOrder(Context context, List<Order> orderList) {

        OurSQLiteOpenHelper ourSQLiteOpenHelper = new OurSQLiteOpenHelper(context);

        ourSQLiteOpenHelper.truncateTable(new DatabaseTable[]{
                OrderTable.getInstance(),
                UnitarySaleTable.getInstance(),
        });
        ourSQLiteOpenHelper.close();

        for (Order order : orderList) {
            new com.cakeclient.Model.Order(context, order).saveToDatabase(context);
        }
        return true;
    }

    private static boolean syncClient(Context context, Client client) {
        //To change body of created methods use File | Settings | File Templates.
        return true;
    }

    public static class storeUpdate extends AsyncTask<Integer, Integer, Integer> {
        Context context;

        public storeUpdate(Context context) {
            this.context = context;
        }

        public Context getContext() {
            return context;
        }

        public void setContext(Context context) {
            this.context = context;
        }

        @Override
        protected Integer doInBackground(Integer... voids) {
            try {
                CakeClientSoapClient server = new CakeClientSoapClient();
                List<Store> stores = server.getStoreList();
                SyncTaskManager.syncStores(context, stores);
            } catch (Exception e) {
                return 0;
            }
            return 100;
        }
    }

    public static class catalogUpdate extends AsyncTask<Integer, Integer, Integer> {
        Context context;

        public catalogUpdate(Context context) {
            this.context = context;
        }

        public Context getContext() {
            return context;
        }

        public void setContext(Context context) {
            this.context = context;
        }


        @Override
        protected Integer doInBackground(Integer... voids) {
            try {
                CakeClientSoapClient server = new CakeClientSoapClient();
                String arg = null;
                if (com.cakeclient.Model.Store.getLocalStore(getContext()) != null) {
                    arg = com.cakeclient.Model.Store.getLocalStore(getContext()).getRemoteID().toString();
                }
                Catalog catalog = server.getCatalog(arg);
                SyncTaskManager.syncCatalog(context, catalog);

            } catch (Exception e) {

                return 0;
            }

            return 100;
        }

    }

    public static class getClientFromID extends AsyncTask<Integer, Integer, Integer> {
        Context context;

        public getClientFromID(Context context) {
            this.context = context;
        }

        public Context getContext() {
            return context;
        }

        public void setContext(Context context) {
            this.context = context;
        }

        @Override
        protected Integer doInBackground(Integer... ids) {
            try {
                CakeClientSoapClient server = new CakeClientSoapClient();
                Client client = server.getClientFromID(ids[0].toString());
                SyncTaskManager.syncClient(context, client);

            } catch (Exception e) {

                return 0;
            }

            return 100;
        }
    }

    public static class SendOrder extends AsyncTask<com.cakeclient.Model.Order, Integer, Integer> {
        ProgressDialog progressDialog;
        Context context;
        private com.cakeclient.Model.Order order;

        public SendOrder(Context context) {
            this.context = context;
        }

        public Context getContext() {
            return context;
        }

        public void setContext(Context context) {
            this.context = context;
        }

        @Override
        protected Integer doInBackground(com.cakeclient.Model.Order... orders) {
            try {
                order = orders[0];
                order = com.cakeclient.Model.Order.getOne(context, order.getIdDB());
                CakeClientSoapClient server = new CakeClientSoapClient();
                if (order.getRemoteID() != null && order.getRemoteID() != 0) {
                    return 100;
                } else {
                    if (order.getClient().getRemoteID() == null || order.getClient().getRemoteID() == 0
                            ) {
                        order.getClient().setRemoteID(server.CreateClient(new SimpleClient(order.getClient())).longValue());
                    }
                    SimpleOrder orderToSend = new SimpleOrder(order);
                    orderToSend.idStore = com.cakeclient.Model.Store.getLocalStore(context).getRemoteID().intValue();
                    order.setRemoteID((server.CreateOrder(orderToSend)).longValue());
                    for (com.cakeclient.Model.UnitarySale unitarySale : order.getUnitarySaleList()) {
                        if (unitarySale.isProduct()) {
                            if (!server.addProductTypeToOrder(unitarySale.getProductType().getRemoteID().intValue(), order.getRemoteID().intValue()))
                                throw new Exception("Failed to addProductTypeToOrder");
                        } else {
                            //on verra
                        }
                    }

                    order.saveToDatabase(context);
                }
            } catch (Exception e) {

                return 0;
            }

            return 100;
        }

        @Override
        protected void onPreExecute() {
            progressDialog = ProgressDialog.show(getContext(), "Envoi vers le serveur", "Communication");
        }

        @Override
        protected void onPostExecute(Integer i) {
            progressDialog.dismiss();
            if (i == 0) {
                new AlertDialog.Builder(context).setMessage("Impossible de Synchroniser avec le serveur")
                        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialogInterface, int i) {
                                dialogInterface.dismiss();
                            }
                        }).setPositiveButton("Dare to ... Try Again", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        new SendOrder(context).execute(new com.cakeclient.Model.Order[]{order});

                    }
                }).show();
            }
        }
    }

    public static class CheckIdClient extends AsyncTask<String, Integer, Boolean> {
        ProgressDialog progressDialog;
        Context context;
        private com.cakeclient.Model.Order order;

        public CheckIdClient(Context context) {
            this.context = context;
        }

        public Context getContext() {
            return context;
        }

        public void setContext(Context context) {
            this.context = context;
        }

        @Override
        protected Boolean doInBackground(String... idsClients) {
            boolean result = true;
            try {
                CakeClientSoapClient serveur = new CakeClientSoapClient();
                for (String idClient : idsClients) {
                    if (serveur.CheckIdClient(idClient) == false) {
                        result = false;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                return false;
            }
            return result;
        }
    }


    public static void sendClient(final Context context, final com.cakeclient.Model.Client client){
        new Thread(new Runnable() {
            @Override
            public void run() {

                CakeClientSoapClient serveur = new CakeClientSoapClient();
                try {
                    if (client.getRemoteID() == null) {
                        client.setRemoteID(Long.valueOf(serveur.CreateClient(new SimpleClient(client))));
                        client.saveToDatabase(context);
                    } else {
                        if(!serveur.UpdateClient(new Client(client))) throw new Exception("Server didn't agree with your request !");
                    }
                } catch (SoapComException e) {
                    e.printStackTrace();
                } catch (SoapClientException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}
